package xin.petstore.framework.file.hash;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;

public class FileHashCalc extends HashCalc {
    private final StreamHashCalc streamHash;
    private final File file;
    private List<HashProgressInterceptor> ltcps = new LinkedList();

    public FileHashCalc(String fileName, String[] algorithms) throws NoSuchAlgorithmException, FileNotFoundException {
        this(new File(fileName), algorithms);
    }

    public FileHashCalc(File file, String[] algorithms) throws FileNotFoundException, NoSuchAlgorithmException {
        this.file = file;
        this.streamHash =
                new StreamHashCalc(new FileInputStream(this.file),
                        algorithms);
        this.streamHash.addHashProgressInterceptor(new FileHashProgressInterceptor());
    }

    @Override
    public long getReadCount() {
        return this.streamHash.getReadCount();
    }

    @Override
    public long getReadLength() {
        return this.streamHash.getReadLength();
    }

    @Override
    public void setReadLength(long len) {
        this.streamHash.setReadLength(len);
    }

    @Override
    public int getBufferSize() {
        return this.streamHash.getBufferSize();
    }

    @Override
    public void setBufferSize(int bufferSize) {
        this.streamHash.setBufferSize(bufferSize);
    }

    public File getFile() {
        return this.file;
    }

    @Override
    public Object getSource() {
        return getFile();
    }

    @Override
    public MessageDigest[] getMessageDigests() {
        return this.streamHash.getMessageDigests();
    }

    @Override
    public byte[][] getByteArrayHash() throws IOException {
        return this.streamHash.getByteArrayHash();
    }

    @Override
    public String[] getHexStringHash() throws IOException {
        return this.streamHash.getHexStringHash();
    }

    @Override
    public void addHashProgressInterceptor(HashProgressInterceptor itcp) {
        this.ltcps.add(itcp);
    }

    @Override
    public void removeHashProgressInterceptor(HashProgressInterceptor itcp) {
        this.ltcps.remove(itcp);
    }

    private class FileHashProgressInterceptor implements HashProgressInterceptor {
        private FileHashProgressInterceptor() {
        }
        @Override
        public void bytesRead(HashBuffer buffer, IHashCalc calc) {
            for (HashProgressInterceptor itcp : FileHashCalc.this.ltcps) {
                itcp.bytesRead(buffer, FileHashCalc.this);
            }
        }
    }
}
